package com.gd.iot.energy.service.systemadmin.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gd.iot.energy.code.ResponseCode;
import com.gd.iot.energy.consts.SystemConsts;
import com.gd.iot.energy.dao.systemadmin.MetermodelPOMapper;
import com.gd.iot.energy.exception.MyException;
import com.gd.iot.energy.po.systemadmin.MetermodelPO;
import com.gd.iot.energy.pojo.common.vo.ColumnVO;
import com.gd.iot.energy.pojo.common.vo.PageVO;
import com.gd.iot.energy.pojo.systemadmin.dto.MetermodelSaveDTO;
import com.gd.iot.energy.pojo.systemadmin.vo.EnumVO;
import com.gd.iot.energy.pojo.systemadmin.vo.MetermodelPageVO;
import com.gd.iot.energy.pojo.systemadmin.vo.MetermodelVO;
import com.gd.iot.energy.pojo.systemadmin.vo.SupplierVO;
import com.gd.iot.energy.service.systemadmin.MetermodelService;
import com.gd.iot.energy.service.systemadmin.SupplierService;
import com.gd.iot.energy.util.CustomBeanUtils;
import com.gd.iot.energy.util.CustomColumnUtil;
import com.gd.iot.energy.util.CustomStrUtil;
import com.gd.iot.energy.util.EnergyTypeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MetermodelServiceImpl extends ServiceImpl<MetermodelPOMapper, MetermodelPO> implements MetermodelService {

    @Resource
    private MetermodelPOMapper metermodelPOMapper;

    @Autowired
    private SupplierService supplierService;

    /**
     * 表头文件
     */
    private static final String MODEL_LIST_COLUMN_FILE_NAME = "systemadmin/metermodel_list.column";

    @Override
    public List<MetermodelVO> getMetermodelVOs(String name) {
        QueryWrapper<MetermodelPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        if (StrUtil.isNotBlank(name)) {
            queryWrapper.like("meter_name", name);
        }
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        List<MetermodelPO> metermodelPOS = metermodelPOMapper.selectList(queryWrapper);
        List<MetermodelVO> metermodelVOS = new ArrayList<>(metermodelPOS.size());
        CustomBeanUtils.convertPojo(metermodelPOS,metermodelVOS,MetermodelVO.class);
        return metermodelVOS;
    }

    @Override
    public PageVO<MetermodelPageVO> getMetermodelPageVOs(String meterName, String meterModel, Integer pageSize,
                                                         Integer pageNo, String orderColumn, String orderType) {
        IPage<MetermodelPO> page = new Page<>(pageNo, pageSize);
        QueryWrapper<MetermodelPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        if (StrUtil.isNotBlank(meterName)) {
            queryWrapper.like("meter_name", meterName.trim());
        }
        if (StrUtil.isNotBlank(meterModel)) {
            queryWrapper.like("meter_model", meterModel.trim());
        }
        if (StrUtil.isNotBlank(orderColumn) && StrUtil.isNotBlank(orderType)) {
            orderColumn = CustomStrUtil.humpToLine(orderColumn);
            queryWrapper.orderBy(true, orderType.equals(SystemConsts.OrderType.ASC.value), orderColumn);
        }
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        IPage<MetermodelPO> equipmentmodelPOIPage = metermodelPOMapper.selectPage(page, queryWrapper);
        PageVO<MetermodelPageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNo);
        List<MetermodelPageVO> roleVOList = convertToMetermodelPageVOList(equipmentmodelPOIPage.getRecords(), pageSize, pageNo);
        pageVO.setData(roleVOList);
        pageVO.setTotal(equipmentmodelPOIPage.getTotal());
        pageVO.setPages(equipmentmodelPOIPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(MODEL_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }
    /**
     * 对象转换
     *
     * @param records
     * @return
     */
    private List<MetermodelPageVO> convertToMetermodelPageVOList(List<MetermodelPO> records, Integer pageSize, Integer pageNo) {
        List<SupplierVO> supplierVOs = supplierService.getSupplierVOs(null);
        Map<Long, String> supplierMap = supplierVOs.stream().collect(
                Collectors.toMap(SupplierVO::getId, SupplierVO::getSupplierName, (key1, key2) -> key2));
        List<MetermodelPageVO> res = new ArrayList<>(records.size());
        MetermodelPageVO metermodelPageVO;

        int i = pageSize * (pageNo - 1) + 1;
        for (MetermodelPO record : records) {
            metermodelPageVO = new MetermodelPageVO();
            metermodelPageVO.setSerialNum(i);
            metermodelPageVO.setId(record.getId());
            metermodelPageVO.setModelSerialnumber(record.getModelSerialnumber());
            metermodelPageVO.setMeterName(record.getMeterName());
            metermodelPageVO.setEnergyTypeName(SystemConsts.EnergyTypeEnum.getNameByValue(record.getEnergyType()));
            metermodelPageVO.setMeterModel(record.getMeterModel());
            metermodelPageVO.setMeterAgreeName(SystemConsts.EquipmentAgreeEnum.getDescByValue(record.getMeterAgree()));
            metermodelPageVO.setMeterWiringWayName(SystemConsts.SysconfigWiringWayEnum.getValueNameByValue(record.getMeterWiringWay()));
            metermodelPageVO.setMeterCalName(SystemConsts.SysconfigCalEnum.getValueNameByValue(record.getMeterCal()));
            metermodelPageVO.setDecimalPoint(record.getDecimalPoint());
            metermodelPageVO.setSupplierName(supplierMap.get(record.getSupplier()));
            metermodelPageVO.setMeterMemo(record.getMeterMemo());
            res.add(metermodelPageVO);
            i++;
        }
        return res;
    }


    @Override
    public Long add(MetermodelSaveDTO metermodelSaveDTO) {
        if (StrUtil.isBlank(metermodelSaveDTO.getMeterName()) ||
                StrUtil.isBlank(metermodelSaveDTO.getMeterModel())) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        MetermodelPO metermodelPO = new MetermodelPO();
        metermodelPO.setCompanyId(0L);
        metermodelPO.setCreateDate(new Date());
        metermodelPO.setEnergyType(SystemConsts.EnergyTypeEnum.WATER.value);
        metermodelPO.setIsDel(SystemConsts.BooleanEnum.FALSE.value);
        metermodelPO.setModifyDate(new Date());
        metermodelPO.setOperatorId(1L);
        metermodelPO.setDecimalPoint(metermodelSaveDTO.getDecimalPoint());
        metermodelPO.setMeterAgree(metermodelSaveDTO.getMeterAgree());
        metermodelPO.setMeterCal(metermodelSaveDTO.getMeterCal());
        metermodelPO.setMeterMemo(metermodelSaveDTO.getMeterMemo());
        metermodelPO.setMeterModel(metermodelSaveDTO.getMeterModel());
        metermodelPO.setMeterName(metermodelSaveDTO.getMeterName());
        metermodelPO.setMeterWiringWay(metermodelSaveDTO.getMeterWiringWay());
        metermodelPO.setModelSerialnumber(metermodelSaveDTO.getModelSerialnumber());
        metermodelPO.setSupplier(metermodelSaveDTO.getSupplier());
        metermodelPO.setArchivesType(metermodelSaveDTO.getArchivesType());
        metermodelPO.setCapacity(metermodelSaveDTO.getCapacity());


        metermodelPOMapper.insert(metermodelPO);
        return metermodelPO.getId();
    }

    @Override
    public boolean update(MetermodelSaveDTO metermodelSaveDTO) {
        if (StrUtil.isBlank(metermodelSaveDTO.getMeterName()) ||
                StrUtil.isBlank(metermodelSaveDTO.getMeterModel())) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        MetermodelPO metermodelPO = new MetermodelPO();
        metermodelPO.setId(metermodelSaveDTO.getId());
        metermodelPO.setModifyDate(new Date());
        metermodelPO.setOperatorId(1L);
        metermodelPO.setDecimalPoint(metermodelSaveDTO.getDecimalPoint());
        metermodelPO.setMeterAgree(metermodelSaveDTO.getMeterAgree());
        metermodelPO.setMeterCal(metermodelSaveDTO.getMeterCal());
        metermodelPO.setMeterMemo(metermodelSaveDTO.getMeterMemo());
        metermodelPO.setMeterModel(metermodelSaveDTO.getMeterModel());
        metermodelPO.setMeterName(metermodelSaveDTO.getMeterName());
        metermodelPO.setMeterWiringWay(metermodelSaveDTO.getMeterWiringWay());
        metermodelPO.setModelSerialnumber(metermodelSaveDTO.getModelSerialnumber());
        metermodelPO.setSupplier(metermodelSaveDTO.getSupplier());
        metermodelPO.setArchivesType(metermodelSaveDTO.getArchivesType());
        metermodelPO.setCapacity(metermodelSaveDTO.getCapacity());

        metermodelPOMapper.updateById(metermodelPO);
        return true;
    }

    @Override
    public boolean delete(List<Integer> ids) {
        if(CollUtil.isEmpty(ids)){
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        //供应商表逻辑删除
        QueryWrapper<MetermodelPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        MetermodelPO metermodelPO = new MetermodelPO();
        metermodelPO.setIsDel(SystemConsts.BooleanEnum.TRUE.value);
        int num = metermodelPOMapper.update(metermodelPO,queryWrapper);

        return num > 0;
    }

    @Override
    public MetermodelSaveDTO getMetermodel(Integer id) {
        MetermodelPO metermodelPO = metermodelPOMapper.selectById(id);
        if(metermodelPO==null||SystemConsts.BooleanEnum.TRUE.value.equals(metermodelPO.getIsDel())){
            throw new MyException(ResponseCode.RECORD_NOT_EXIST);
        }

        MetermodelSaveDTO metermodelSaveDTO = new MetermodelSaveDTO();
        metermodelSaveDTO.setId(metermodelPO.getId());
        metermodelSaveDTO.setModelSerialnumber(metermodelPO.getModelSerialnumber());
        metermodelSaveDTO.setMeterName(metermodelPO.getMeterName());
        metermodelSaveDTO.setMeterModel(metermodelPO.getMeterModel());
        metermodelSaveDTO.setMeterAgree(metermodelPO.getMeterAgree());
        metermodelSaveDTO.setMeterWiringWay(metermodelPO.getMeterWiringWay());
        metermodelSaveDTO.setMeterCal(metermodelPO.getMeterCal());
        metermodelSaveDTO.setSupplier(metermodelPO.getSupplier());
        metermodelSaveDTO.setDecimalPoint(metermodelPO.getDecimalPoint());
        metermodelSaveDTO.setArchivesType(metermodelPO.getArchivesType());
        metermodelSaveDTO.setMeterMemo(metermodelPO.getMeterMemo());
        metermodelSaveDTO.setCapacity(metermodelPO.getCapacity());

        return metermodelSaveDTO;
    }

    @Override
    public Map<String, List<EnumVO>> getEnums() {
        Map<String, List<EnumVO>> resultMap = new HashMap<>();

        List<EnumVO> agree = new ArrayList<>();
        for (SystemConsts.EquipmentAgreeEnum value : SystemConsts.EquipmentAgreeEnum.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            vo.setValueName(value.valueName);
            vo.setDesc(value.desc);
            agree.add(vo);
        }

        List<EnumVO> wiring = new ArrayList<>();
        for (SystemConsts.SysconfigWiringWayEnum value : SystemConsts.SysconfigWiringWayEnum.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            vo.setValueName(value.valueName);
            vo.setDesc(value.desc);
            wiring.add(vo);
        }

        List<EnumVO> cal = new ArrayList<>();
        for (SystemConsts.SysconfigCalEnum value : SystemConsts.SysconfigCalEnum.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            vo.setValueName(value.valueName);
            vo.setDesc(value.desc);
            cal.add(vo);
        }

        List<EnumVO> archives = new ArrayList<>();
        for (SystemConsts.ArchivesTypeEnum value : SystemConsts.ArchivesTypeEnum.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            vo.setValueName(value.valueName);
            vo.setDesc(value.desc);
            archives.add(vo);
        }

        List<EnumVO> decimalPoint = new ArrayList<>();
        for (SystemConsts.DecimalPointEnum value : SystemConsts.DecimalPointEnum.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            vo.setValueName(value.valueName);
            decimalPoint.add(vo);
        }

        resultMap.put("agree", agree);
        resultMap.put("wiring", wiring);
        resultMap.put("cal", cal);
        resultMap.put("archives", archives);
        resultMap.put("decimalPoint", decimalPoint);
        return resultMap;
    }
}
